#单一职责原则Single Responsibility Principle

"""定义：一个类或者一个接口，最好只负责一项职责。

问题由来：类T负责两个不同的职责P1和P2。由于职责P1需要发生改变而需要修改T类时，有可能导致原来运行正常的职责P2功能发生故障。

解决方法：遵循单一职责原则。分别建立两个类T1和T2，使类T1负责职责P1，类T2负责职责P2。这样，当修改类T1也不会影响职责P2；同理，当修改类T2时不会影响职责P1。
"""
#里氏替换原则Liskov Substitution Principle
"""定义2：所有引用基类的地方必须能透明地使用其子类的对象。

问题由来：有一功能P1，由类A完成。现需要将功能P1进行扩展，扩展后的功能为P，其中P由原有功能P1与新功能P2组成。新功能P由类A的子类B来完成，则子类B在完成新功能P2的同时，有可能会导致原有功能P1发生故障。

解决方案：当使用继承时，遵循里氏替换原则。类B继承类A时，除添加新的方法完成新增功能P2外，尽量不要重写父类A的方法，也尽量不要重载父类A的方法。

继承包含这样一层含义：父类中凡是已经实现好的方法（相对于抽象方法而言），实际上是在设定一系列的规范和契约，虽然它不强制要求所有的子类必须遵从这些契约，但是如果子类对这些非抽象方法任意修改，就会对整个继承体系造成破坏。而里氏替换原则就是表达了这一层含义。

继承作为面向对象三大特性之一，在给程序设计带来巨大便利的同时，也带来了弊端。比如使用继承会给程序带来侵入性，程序的可移植性降低，增加了对象间的耦合性，如果一个类被其他的类所继承，则当这个类需要修改时，必须考虑到所有的子类，并且父类修改后，所有涉及到子类的功能都有可能会产生故障。
"""
#依赖倒置原则Dependence Inversion Principle

"""定义：高层模块不应该依赖低层模块，二者都应该依赖其抽象；抽象不应该依赖细节；细节应该依赖抽象。其核心思想是：依赖于抽象。

问题由来：类A直接依赖类B，假如要将类A改为依赖类C，则必须通过修改类A的代码来达成。这种场景下，类A一般是高层模块，负责复杂的业务逻辑；类B和类C是低层模块，负责基本的原子操作；假如修改类A，会给程序带来不必要的风险。

解决方案：将类A修改为依赖接口I，类B和类C各自实现接口I，类A通过接口I间接与类B或者类C发生联系，则会大大降低修改类A的几率。
"""
#接口隔离原则Interface Segregation Principle

"""定义：客户端不应该依赖它不需要的接口；一个类对另一个类的依赖应该建立在最小的接口上。 否则将会造成接口污染。类A通过接口I依赖类B，类C通过接口I依赖类D，如果接口I对于类A和类B来说不是最小接口，则类B和类D必须去实现他们不需要的方法。

解决方案：将臃肿的接口I拆分为独立的几个接口，类A和类C分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则。
"""
#迪米特法则Demeter Principle

"""定义：一个对象应该对其他对象保持最少的了解。其核心精神是：不和陌生人说话，通俗之意是一个对象对自己需要耦合关联调用的类应该知道的更少。这样会导致类之间的耦合度降低，每个类都尽量减少对其他类的依赖，因此，这也很容易使得系统的功能模块相互独立，之间不存在很强的依赖关系。

问题由来：类与类之间的关系越密切，耦合度越大，当一个类发生改变时，对另一个类的影响也越大。

解决方案：尽量降低类与类之间的耦合。
"""
#合成复用原则Composite Reuse Principle

"""原则是尽量使用合成/聚合的方式，而不是使用继承。
"""
#开闭原则Open Close Principle

"""定义：一个软件实体如类、模块和函数应该对扩展开放，对修改关闭。

问题由来：在软件的生命周期内，因为变化、升级和维护等原因需要对软件原有代码进行修改时，可能会给旧代码中引入错误，也可能会使我们不得不对整个功能进行重构，并且需要原有代码经过重新测试。

解决方案：当软件需要变化时，尽量通过扩展软件实体的行为来实现变化，而不是通过修改已有的代码来实现变化。
"""